package com.kamikaze.docidset.impl;

import java.io.IOException;
import java.io.Serializable;

import org.apache.lucene.search.DocIdSet;
import org.apache.lucene.search.DocIdSetIterator;

import com.kamikaze.docidset.api.DocSet;
import com.kamikaze.docidset.utils.IntArray;

public class IntArrayDocIdSet extends DocIdSet implements DocSet,Serializable
{
  
  private static final long serialVersionUID = 1L;
  
 

  private IntArray array = null;
  private int pos = -1;
  
  
  public IntArrayDocIdSet(int length)
  {
    array = new IntArray(length);
  }
  
  public IntArrayDocIdSet()
  {
	  array = new IntArray();
  }
  
  
  public void addDoc(int docid)
  {
	++pos;
    array.add(docid);
  }
  
  

  protected int binarySearchForNearest(int val, int begin, int end) {
   
      if(pos == -1)
        return -1;
    
      int mid = (begin + end) / 2;
      // Find number equal or greater than the target.
      if (mid == end || (array.get(mid) <= val && array.get(mid+1) > val))
          return mid+1<=pos?mid+1:-1;
      
      else if (array.get(mid) < val)
          return binarySearchForNearest(val,  mid + 1, end);
      else
          return binarySearchForNearest(val,  begin, mid);
  }
  
  class IntArrayDocIdSetIterator extends DocIdSetIterator
  {
    int lastReturn  = -1;
    int cursor = -1;
    

    @Override
    public int doc()
    {
        return lastReturn;
    }

    @Override
    public boolean next() throws IOException
    {
      if(++cursor <= pos)
      {
        lastReturn = array.get(cursor);
        return true;
      }
      return false;
    }

    @Override
    public boolean skipTo(int target) throws IOException
    {
      int index = binarySearchForNearest(target, 0, pos);
      if(index == -1)
      {
        cursor = pos;
        lastReturn = -1;
        return false;
      }
      else
      { cursor = index;
        lastReturn = array.get(cursor);
        return true;
      }
    }

    @Override
    public int getCursor()
    {
      return cursor;
    }
  }
 
  @Override
  public DocIdSetIterator iterator()
  {
    return new IntArrayDocIdSetIterator();
  }

  public int size()
  {
    return pos+1;
  }

  
  public int find(int val)
  {
    IntArrayDocIdSetIterator dcit = new IntArrayDocIdSetIterator();
    try
    {
      dcit.skipTo(val);
      if(dcit.doc() == val)
        return dcit.getCursor();
    }
    catch (IOException e)
    {
       e.printStackTrace();
    }
    return -1;
  }






  
}
